package com.cloud.rou.im.router;
import com.cloud.rou.im.cluster.naming.node.ImServerInstance;
import com.cloud.rou.im.protocol.codec.DataPacketDecoder;
import com.cloud.rou.im.protocol.codec.DataPacketEncoder;
import com.cloud.rou.im.router.context.ChannelAndInstance;
import com.cloud.rou.im.router.context.ImServerInstanceContext;
import com.cloud.rou.im.router.handler.BizHandler;
import com.cloud.rou.im.router.handler.ClientLoginHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.Optional;


@Slf4j
@Data
public class WorkerReSender {
    //连接远程节点的Netty通道
    private Channel channel;
    //连接远程节点的POJO信息
    private ImServerInstance remoteNode;
    /**
     * 连接标记
     */
    private boolean connectFlag = false;
    private Bootstrap b;
    private EventLoopGroup g;
    public WorkerReSender(ImServerInstance n) {
        this.remoteNode = n;
        b = new Bootstrap();
        g = new NioEventLoopGroup();
    }
    /**
     * 连接和重连
     */
 /*   public void doConnect(ImServerInstance instance) {
        // 服务器ip地址
        String host = remoteNode.getHost();
        // 服务器端口
        int port = Integer.parseInt(remoteNode.getPort());
        try {
            if (b != null &&b.group() == null) {
                b.group(g);
                b.channel(NioSocketChannel.class);
                b.option(ChannelOption.SO_KEEPALIVE, true);
                b.option(ChannelOption.ALLOCATOR,
                        PooledByteBufAllocator.DEFAULT);
                b.remoteAddress(host, port);
                // 设置通道初始化
                b.handler(
                        new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new DataPacketEncoder());
                        ch.pipeline().addLast(new DataPacketDecoder());
                        ch.pipeline().addLast(new ClientLoginHandler());
                        ch.pipeline().addLast(new BizHandler());
                    }
                }
                );

                ChannelFuture f = b.connect();
                f.addListener(future -> {
                    if(future.isSuccess()){
                        System.out.println("连接成功："+instance.getId());
                        ImServerInstanceContext context = ImServerInstanceContext.getInstance();
                        Channel channel = f.channel();
                        boolean add = context.add(ChannelAndInstance.builder().channel(channel).instance(instance).build());
                       if(!add){
                           channel.close();
                       }
                    }
                });
                f.sync();
               // f.addListener(connectedListener);
                // 阻塞
                 f.channel().closeFuture().sync();
            } else if (b.group() != null) {

                ChannelFuture f = b.connect();
                //f.addListener(connectedListener);
            }
        } catch (Exception e) {

        }

    }*/
    public void doConnect(ImServerInstance instance) {
        NioEventLoopGroup g = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        try {
            b.group(g);
            b.channel(NioSocketChannel.class);
            // b.option(ChannelOption.SO_KEEPALIVE, true);
            b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
            b.remoteAddress("127.0.0.1", Integer.valueOf(instance.getPort()));
            b.handler(new LoggingHandler(LogLevel.INFO));
            // 设置通道初始化
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) {
                    ch.pipeline().addLast("decoder", new DataPacketDecoder());
                    ch.pipeline().addLast("encoder", new DataPacketEncoder());
                    ch.pipeline().addLast(new ClientLoginHandler());
                    ch.pipeline().addLast(new BizHandler());
                }
            });

            ChannelFuture f = b.connect();
            f.addListener(future -> {
                if(future.isSuccess()){
                    System.out.println("连接成功："+instance.getId());
                    ImServerInstanceContext context = ImServerInstanceContext.getInstance();
                    Channel channel = f.channel();
                    boolean add = context.add(ChannelAndInstance.builder().channel(channel).instance(instance).build());
                    if(add){
                        channel.close();
                        System.out.println("连接失败："+instance.getId());
                    }
                }
            });
            // 阻塞
            f.channel().closeFuture().sync();
        } catch (Exception e) {}
        finally {
            g.shutdownGracefully();
        }
    }
}
